#include <cstddef> // For std::nullptr_t
#include <stdexcept>
#include <iostream>
template<typename T>
class weak_ptr; // 前置声明

template<typename T>
class shared_ptr {
private:
    T* ptr; // 指向实际管理的资源
    std::size_t* strong_count; // 用于跟踪共享该资源的智能指针数量的引用计数
    std::size_t* weak_count;

public:
    // 构造函数
    explicit shared_ptr(T* p = nullptr) : ptr(p), strong_count(p ? new std::size_t(1) : nullptr), weak_count(p ? new std::size_t(0) : nullptr) {}

    // 复制构造函数
    shared_ptr(const shared_ptr& other) : ptr(other.ptr), strong_count(other.strong_count) {
            increment_count();
    }

    // 析构函数
    ~shared_ptr() {
        std::cout << "Destroying shared_ptr, use count before: " << (strong_count ? *strong_count : 0) << '\n';
        release_resource();
    }

    // 复制赋值操作符
    shared_ptr& operator=(const shared_ptr& other) {
        if (this != &other) {
            release_resource();
            ptr = other.ptr;
            strong_count = other.strong_count;
            weak_count = other.weak_count;
            increment_count();
        }
        return *this;
    }

    // 移动构造函数
    shared_ptr(shared_ptr&& other) noexcept
        : ptr(other.ptr), strong_count(other.strong_count), weak_count(other.weak_count) {
        other.ptr = nullptr;
        other.strong_count = nullptr;
        other.weak_count = nullptr;
    }

    // 移动赋值操作符
    shared_ptr& operator=(shared_ptr&& other) noexcept {
        if (this != &other) {
            release_resource();
            ptr = other.ptr;
            strong_count = other.strong_count;
            weak_count = other.weak_count;
            other.ptr = nullptr;
            other.strong_count = nullptr;
            other.weak_count = nullptr;
        }
        return *this;
    }

    T* get() const { return ptr; }
    std::size_t use_count() const { return strong_count ? *strong_count : 0; }
    T& operator*() const {
        if (!ptr) throw std::runtime_error("Attempted to dereference a null shared_ptr");
        return *ptr;
    }
    T* operator->() const {
        if (!ptr) throw std::runtime_error("Attempted to access member of a null shared_ptr");
        return ptr;
    }
    // 添加显式布尔类型转换运算符
    explicit operator bool() const { return ptr != nullptr; }
    void swap(shared_ptr& other) noexcept {
        std::swap(ptr, other.ptr);
        std::swap(strong_count, other.strong_count);
        std::swap(weak_count, other.weak_count);
    }
    // reset 方法
    void reset(T* p = nullptr) {
        shared_ptr<T>(p).swap(*this);
    }
    //返回一个布尔值，指示当前 shared_ptr 是否是唯一拥有对象的智能指针。
    bool unique() const {
        return use_count() == 1;
    }
    // 从weak_ptr构建shared_ptr的构造函数
    // Constructor from weak_ptr
    explicit shared_ptr(const weak_ptr<T>& weak) {
        if (weak.get_strong_count() && *weak.get_strong_count() > 0) {
            ptr = weak.get_ptr();
            strong_count = weak.get_strong_count();
            weak_count = weak.get_weak_count();
            (*strong_count)++;
        } else {
            // 如果没有强引用，则初始化为空
            ptr = nullptr;
            strong_count = nullptr;
            weak_count = nullptr;
        }
    }
    // 提供访问器
    T* get_ptr() const { return ptr; }
    std::size_t* get_strong_count() const { return strong_count; }
    std::size_t* get_weak_count() const { return weak_count; }
    friend class weak_ptr<T>; // 友元声明

private:
    void increment_count() {
        if (strong_count) {
            (*strong_count)++;
        }
    }
    void release_resource() {
        if (strong_count) {
            if (--(*strong_count) == 0) {
                std::cout << "Deleting managed object and strong count\n";
                delete ptr;
                if (weak_count && --(*weak_count) == 0) {
                    std::cout << "Deleting weak count\n";
                    delete weak_count;
                    weak_count = nullptr;
                }
            }
            strong_count = nullptr;
        }
        ptr = nullptr;
    }
};
template<typename T>
class weak_ptr {
private:
    T* ptr;
    std::size_t* strong_count;
    std::size_t* weak_count;

public:
    weak_ptr() : ptr(nullptr), strong_count(nullptr), weak_count(nullptr) {}

    // 从shared_ptr构造weak_ptr
    weak_ptr(const shared_ptr<T>& shared)
        : ptr(shared.get_ptr()), strong_count(shared.get_strong_count()), weak_count(shared.get_weak_count()) {
        if (weak_count) {
            (*weak_count)++;
        }
    }

    ~weak_ptr() {
        if (weak_count && --(*weak_count) == 0) {
            if (strong_count && *strong_count == 0) {
                delete ptr;
                delete strong_count;
                strong_count = nullptr;
            }
            delete weak_count;
            weak_count = nullptr;
        }
    }

    bool expired() const {
        return strong_count == nullptr || *strong_count == 0;
    }

    shared_ptr<T> lock() const {
        if (expired()) {
            return shared_ptr<T>();
        } else {
            return shared_ptr<T>(*this);
        }
    }
    // 访问器，返回原始指针
    T* get_ptr() const { return ptr; }
    // 访问器，返回强引用计数
    std::size_t* get_strong_count() const { return strong_count; }
    // 访问器，返回弱引用计数
    std::size_t* get_weak_count() const { return weak_count; }
};
#include <iostream>
struct Test {
    int id;
    Test(int i) : id(i) { std::cout << "Test " << id << " created\n"; }
    ~Test() { std::cout << "Test " << id << " destroyed\n"; }
};

int main() {
    {
        shared_ptr<Test> sp1(new Test(1)); // 创建一个Test对象，其id为1
        std::cout << "Use strong_count of sp1: " << sp1.use_count() << '\n';

        weak_ptr<Test> wp1(sp1); // 创建一个weak_ptr，从sp1初始化
        std::cout << "sp1 is expired: " << (wp1.expired() ? "Yes" : "No") << '\n';

        {
            shared_ptr<Test> sp2 = wp1.lock(); // 试图从wp1锁定一个shared_ptr
            if (sp2) {
                std::cout << "Managed object from wp1 locked\n";
                std::cout << "Use strong_count of sp1 now: " << sp1.use_count() << '\n';
            }
        } // sp2 goes out of scope

        std::cout << "Use strong_count of sp1 after sp2 goes out: " << sp1.use_count() << '\n';

        sp1.reset(); // 重置sp1，应该会导致Test对象被销毁
        std::cout << "sp1 is expired after reset: " << (wp1.expired() ? "Yes" : "No") << '\n';

        shared_ptr<Test> sp3 = wp1.lock(); // 尝试再次从wp1锁定一个shared_ptr
        if (!sp3) {
            std::cout << "No managed object, wp1 is expired\n";
        }
    } // All smart pointers go out of scope

    return 0;
}